
#ifndef __BROKER_5_SERVER_H
#define __BROKER_5_SERVER_H

#include <apr.h>
#include <apr_atomic.h>
#include "BrokerMessage.h"
#include "HTTPServer.h"

#define BROKERNAME "broker"

/** The class of the main broker server. This is a single TCP socket
 * server that serves HTTP GET, HTTP POST and the encrypted
 * communication protocol of the broker. */
class Broker5Server : public HTTPServer
{
   public:
      /** Constructor for the broker server class.
      * 
      * @param inoofthreads The number of threads to use for serving
      * connections.
      * 
      * @param iportno The port to listen on.
      * 
      * @param ihostname The host (interface) to listen on.
      * 
      * @param upperpool The memory pool to derive this server memory
      * pool from. */
      Broker5Server(int inoofthreads, int iportno, const char *ihostname, apr_pool_t *upperpool) :
         HTTPServer(inoofthreads, iportno, ihostname, upperpool) {}
      /** Destructor for the broker server. */
      ~Broker5Server() {}
      int checkBlock(const APRTable *headertable, const char *data_store_id, apr_pool_t *t_mp);
      int divineMeaning(BrokerMessage &msgin, BrokerMessage &msgout, int i, apr_pool_t *t_mp);
      int checkNewUser(BrokerMessage &msgin);
      int checkPermissionsOkay(BrokerMessage &msgin);
      void generateConsole(int i, apr_pool_t *t_mp);
      void understandPOSTData(APRTable *data);
      int serveStreamFromSystemList(APRTable *htable, int i, apr_pool_t *mp, const char **systemwhitelist);
      void streamPlainTextKey(int threadid, const char *extended_ownername, const char *tpwd);
      void handleGETSession(int i, apr_pool_t *t_mp);
      void handlePOSTSession(int i, apr_pool_t *t_mp);
      void handleBrokerSession(int i, apr_pool_t *t_mp);
      void handleClientsOnThread(int threadid, apr_pool_t *localmp);
      static void *handleClientsOnThreadStatic(apr_thread_t *tthread, void *args);
      /** Get the client handler as a function pointer. */
      virtual functor getClientHandlerFunction() const { return (functor)(&handleClientsOnThreadStatic); }
      /** A holding structure for pointers to each of the
       * databases. */
      AllDBs *dbs;
};

#endif
